home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 41 / Amiga Format CD41 (1999-06)(Future Publishing)(GB)[!][issue 1999-07].iso / -seriously_amiga- / programming / other / gtlayout / source / lt_imsg.c < prev    next >
C/C++ Source or Header  |  1999-04-19  |  5KB  |  216 lines

  1. /*
  2. **    GadTools layout toolkit
  3. **
  4. **    Copyright © 1993-1998 by Olaf `Olsen' Barthel
  5. **        Freely distributable.
  6. **
  7. **    :ts=4
  8. */
  9.  
  10. #ifndef _GTLAYOUT_GLOBAL_H
  11. #include "gtlayout_global.h"
  12. #endif
  13.  
  14. /*****************************************************************************/
  15.  
  16. #include <exec/memory.h>
  17.  
  18. /*****************************************************************************/
  19.  
  20. #include "Assert.h"
  21.  
  22. #define MESSAGE_COOKIE 0x19138AFB
  23.  
  24. /****** gtlayout.library/LT_GetIMsg ******************************************
  25. *
  26. *   NAME
  27. *    LT_GetIMsg -- Retrieve the next pending IntuiMessage
  28. *                  from the window associated with a
  29. *                  LayoutHandle.
  30. *
  31. *   SYNOPSIS
  32. *    IntuiMessage = LT_GetIMsg(Handle);
  33. *         D0                     A0
  34. *
  35. *    struct IntuiMessage *LT_GetIMsg(LayoutHandle *);
  36. *
  37. *   FUNCTION
  38. *    This routine will handle most of the input loop for
  39. *    you. Just pass the pointer to the layout handle in,
  40. *    check if the result code is non-null, copy the data
  41. *    you need and reply the message via LT_ReplyIMsg().
  42. *
  43. *    You will still need to wait for new input, as LT_GetIMsg
  44. *    will poll the MsgPort of the window.
  45. *
  46. *    LT_GetIMsg() will try its best to distinguish between
  47. *    different LayoutHandles sharing the same Window->UserPort.
  48. *    If it finds that the window the message was sent to is
  49. *    using a different LayoutHandle, it will switch to using
  50. *    this handle (V13).
  51. *
  52. *   INPUTS
  53. *    Handle - Pointer to LayoutHandle structure
  54. *
  55. *   RESULT
  56. *    IntuiMessage - Pointer to IntuiMessage structure
  57. *
  58. *   NOTES
  59. *    You *must not* make any assumptions about the contents
  60. *    of the IntuiMessage structure except for the following
  61. *    entries:
  62. *
  63. *       Class
  64. *       Code
  65. *       Qualifier
  66. *       IAddress
  67. *
  68. *    When finished, you must dispose the IntuiMessage via
  69. *    LT_ReplyIMsg or memory will be lost which can never
  70. *    be reclaimed.
  71. *
  72. *    DO NOT CALL LT_HandleInput() ON THE DATA YOU RECEIVE
  73. *    FROM LT_GetIMsg() AS LT_GetIMsg() ALREADY DOES ALL THE
  74. *    MAGIC LT_HandleInput() OTHERWISE WOULD NEED TO DO!
  75. *    IF YOU STILL DO CALL LT_HandleInput() ON THE DATA YOU
  76. *    WILL RECEIVE `GHOST' EVENTS.
  77. *
  78. *   SEE ALSO
  79. *    gtlayout.library/LT_ReplyIMsg
  80. *
  81. ******************************************************************************
  82. *
  83. */
  84.  
  85. struct IntuiMessage * LIBENT
  86. LT_GetIMsg(REG(a0) struct LayoutHandle *Handle)
  87. {
  88.     if(Handle)
  89.     {
  90.         struct IntuiMessage *Msg = GT_GetIMsg(Handle->Window->UserPort);
  91.  
  92.         if(Msg)
  93.         {
  94.             struct IntuiMessage *Clone;
  95.  
  96.                 // For multiple handles sharing the same UserPort
  97.  
  98.             if(Msg->IDCMPWindow->UserData && !((ULONG)Msg->IDCMPWindow->UserData & 1))
  99.             {
  100.                 LayoutHandle *Local = (LayoutHandle *)Msg->IDCMPWindow->UserData;
  101.  
  102.                 if(Local->PointBack == Local)
  103.                     Handle = Local;
  104.                 else
  105.                     return(Msg);
  106.             }
  107.             else
  108.                 return(Msg);
  109.  
  110.             if(Msg->Class == IDCMP_SIZEVERIFY && Handle->ResizeObject != NULL)
  111.             {
  112.                     // They're coming to take me away, HAHA!
  113.  
  114.                 Handle->SizeVerified    = TRUE;
  115.                 Handle->SizeWidth        = Handle->Window->Width;
  116.                 Handle->SizeHeight        = Handle->Window->Height;
  117.  
  118.                 LTP_StripGadgets(Handle,Handle->List);
  119.  
  120.                 #ifdef DO_BOOPSI_KIND
  121.                 {
  122.                     LTP_StripGadgets(Handle,(struct Gadget *)Handle->BOOPSIList);
  123.                 }
  124.                 #endif    /* DO_BOOPSI_KIND */
  125.  
  126.                     // Fake a null event, otherwise the following
  127.                     // IDCMP_NEWSIZE would probably not get through
  128.  
  129.                 if(Clone = (struct IntuiMessage *)AllocMem(sizeof(struct IntuiMessage),MEMF_ANY))
  130.                 {
  131.                     CopyMem(Msg,Clone,sizeof(struct IntuiMessage));
  132.  
  133.                     Clone->Class                        = NULL;
  134.                     Clone->ExecMessage.mn_Node.ln_Name    = (char *)MESSAGE_COOKIE;
  135.                     Clone->ExecMessage.mn_Node.ln_Pri     = -114;
  136.                     Clone->ExecMessage.mn_ReplyPort        = (struct MsgPort *)Clone;
  137.                     Clone->SpecialLink                    = (struct IntuiMessage *)Clone;
  138.  
  139.                     GT_ReplyIMsg(Msg);
  140.                 }
  141.             }
  142.             else
  143.             {
  144.                 if(Clone = (struct IntuiMessage *)AllocMem(sizeof(struct IntuiMessage),MEMF_ANY))
  145.                 {
  146.                     CopyMem(Msg,Clone,sizeof(struct IntuiMessage));
  147.  
  148.                     Clone->ExecMessage.mn_Node.ln_Name    = (char *)MESSAGE_COOKIE;
  149.                     Clone->ExecMessage.mn_Node.ln_Pri     = -114;
  150.                     Clone->ExecMessage.mn_ReplyPort        = (struct MsgPort *)Clone;
  151.                     Clone->SpecialLink                    = (struct IntuiMessage *)Clone;
  152.  
  153.                     GT_ReplyIMsg(Msg);
  154.  
  155.                     LT_HandleInput(Handle,Clone->Qualifier,&Clone->Class,&Clone->Code,(struct Gadget **)&Clone->IAddress);
  156.                 }
  157.             }
  158.  
  159.             if(Clone)
  160.                 return(Clone);
  161.             else
  162.                 GT_ReplyIMsg(Msg);
  163.         }
  164.     }
  165.  
  166.     return(NULL);
  167. }
  168.  
  169.  
  170. /*****************************************************************************/
  171.  
  172.  
  173. /****** gtlayout.library/LT_ReplyIMsg ******************************************
  174. *
  175. *   NAME
  176. *    LT_ReplyIMsg -- Dispose of an IntuiMessage received
  177. *
  178. *   SYNOPSIS
  179. *    LT_ReplyIMsg(IntuiMessage);
  180. *                     A0
  181. *
  182. *    VOID LT_ReplyIMsg(struct IntuiMessage *);
  183. *
  184. *   FUNCTION
  185. *    This routine complements LT_GetIMsg().
  186. *
  187. *   INPUTS
  188. *    IntuiMessage - Pointer to IntuiMessage structure,
  189. *        passing NULL is harmless.
  190. *
  191. *   RESULT
  192. *    none
  193. *
  194. *   NOTES
  195. *    Only pass IntuiMessages you received via LT_GetIMsg,
  196. *    or things will get tough.
  197. *
  198. *   SEE ALSO
  199. *    gtlayout.library/LT_GetIMsg
  200. *
  201. ******************************************************************************
  202. *
  203. */
  204.  
  205. VOID LIBENT
  206. LT_ReplyIMsg(REG(a0) struct IntuiMessage *Msg)
  207. {
  208.     if(Msg)
  209.     {
  210.         if(Msg->SpecialLink == (struct IntuiMessage *)Msg && Msg->ExecMessage.mn_Node.ln_Name == (char *)MESSAGE_COOKIE && Msg->ExecMessage.mn_Node.ln_Pri == -114 && Msg->ExecMessage.mn_ReplyPort == (struct MsgPort *)Msg)
  211.             FreeMem(Msg,sizeof(struct IntuiMessage));
  212.         else
  213.             GT_ReplyIMsg(Msg);
  214.     }
  215. }
  216.